﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Management;

namespace MailTo
{
    static class MailTo
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]

        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Settings LocalSettings = new Settings();
            String[] CmdLineArgs = Environment.GetCommandLineArgs();
            if (CmdLineArgs.Length == 1)
            {//Show the form, we need the settings            
                Application.Run(new frm_main(LocalSettings));
            }
            else
            {//Test to see if the registry values are already set.  If not we need to set them
                if (LocalSettings.LM_Key_Domain == null)
                {//Domain Not set in LM key
                    if (LocalSettings.CU_Key_Domain == null)
                    {//Domain also not set in CU key               
                        Application.Run(new frm_main(LocalSettings));
                        return;//exits main
                    }
                    else LocalSettings.Domain = LocalSettings.CU_Key_Domain.ToString();
                }
                else LocalSettings.Domain = LocalSettings.LM_Key_Domain.ToString();

                //Ok, now lets get the protocol
                if (LocalSettings.LM_Key_Protocol == null)
                {//Protocol not present in LM key
                    if (LocalSettings.CU_Key_Protocol == null)
                    {
                        LocalSettings.Protocol = "https";
                    }
                    else LocalSettings.Protocol = LocalSettings.CU_Key_Protocol.ToString();
                }
                else LocalSettings.Protocol = LocalSettings.LM_Key_Protocol.ToString();

                //Now lets get the GAFD setting
                if (LocalSettings.LM_Key_GAFD == null)
                {//GAFD not set in local machine
                    if (LocalSettings.CU_Key_GAFD == null)
                    {//In needs to be there open the form
                        Application.Run(new frm_main(LocalSettings));
                        return;
                    }
                    else
                    {//The GAFD setting is stored in the CU
                        LocalSettings.GAFD = LocalSettings.CU_Key_GAFD.ToString();
                    }
                }
                else LocalSettings.GAFD = LocalSettings.LM_Key_GAFD.ToString();
                //At this time, we have the settings, and something has been sent into the program
                //We want to Open gmail, passing the data sent from the mailto link to gmail

                //With the new syntax, we no longer need to parse the mailto link
                //NewEmail MyMessage = LocalSettings.ParseEmailString(CmdLineArgs[1]);
                NewEmail MyMessage = new NewEmail(CmdLineArgs[1]);
                MyMessage.SendEmail(LocalSettings.Domain, LocalSettings.Protocol, LocalSettings.GAFD);
            }//end else for comand line arguements
            //yeah, we are done
        }//end main
    }//end the mailto class

    public class Settings
    {//This class holds the settings, easier than duplicating code in 2 places
        //Location of registry data can be saved (all users)
        String Reg_DATA_LM = "HKEY_LOCAL_MACHINE\\SOFTWARE\\MailTo\\";
        //Lcoation of registry where data can be saved (current user)
        String Reg_DATA_CU = "HKEY_CURRENT_USER\\SOFTWARE\\MailTo\\";

        //These object will hold the values returned from registry
        public Object LM_Key_Domain;
        public Object CU_Key_Domain;
        public Object LM_Key_Protocol;
        public Object CU_Key_Protocol;
        public Object LM_Key_GAFD;
        public Object CU_Key_GAFD;

        //Some shit to keep track of
        public String Domain;
        public String Protocol; //http or https
        public String GAFD; //User is using gafd or not
        //An array to make this just slightly easier
        String[] LocalSettings = new string[3];//Domain, Protocol, and GAFD
        public String BaseURL;//URL to the compose window
        public String cc, bcc, sub, body, to;
        public String[] splitTo;
        

        public Settings()
        {//Constructor, gets the values from the registry
            LM_Key_Domain = Registry.GetValue(Reg_DATA_LM, "Domain", null);
            CU_Key_Domain = Registry.GetValue(Reg_DATA_CU, "Domain", null);
            LM_Key_Protocol = Registry.GetValue(Reg_DATA_LM, "Protocol", null);
            CU_Key_Protocol = Registry.GetValue(Reg_DATA_CU, "Protocol", null);
            LM_Key_GAFD = Registry.GetValue(Reg_DATA_LM, "GAFD", null);
            CU_Key_GAFD = Registry.GetValue(Reg_DATA_CU, "GAFD", null);
        }

        public void Set(String[] Settings, Boolean LocalMachine)
        {//Sets the registry values based on the array passed in
            if (LocalMachine == true)
            {//set the settings for the local machines
                try
                {
                    Registry.SetValue(Reg_DATA_LM, "Domain", Settings[0], RegistryValueKind.String);
                    Registry.SetValue(Reg_DATA_LM, "Protocol", Settings[1], RegistryValueKind.String);
                    Registry.SetValue(Reg_DATA_LM, "GAFD", Settings[2], RegistryValueKind.String);
                    Registry.SetValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\mailto\\shell\\open\\command", "", "\"" + (Environment.GetCommandLineArgs())[0] + "\" \"%1\"");
                }
                catch (Exception e)
                {
                    MessageBox.Show("You have insufficient permissions to apply these settings to all uesrs.", "Access Privilege Alert!");
                }
            }
            else
            {// set the settings for current user only, note: LM overrides CU
                Registry.SetValue(Reg_DATA_CU, "Domain", Settings[0], RegistryValueKind.String);
                Registry.SetValue(Reg_DATA_CU, "Protocol", Settings[1], RegistryValueKind.String);
                Registry.SetValue(Reg_DATA_CU, "GAFD", Settings[2], RegistryValueKind.String);
                Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Classes\\mailto\\shell\\open\\command", "", "\"" + (Environment.GetCommandLineArgs())[0] + "\" \"%1\"");
            }
        }//End Set Method

        [Obsolete("This method is obsolete, No longer a need to parse", true)]
        public NewEmail ParseEmailString(String Line)
        {//This method parses the incoming string from the mailto, and determines the proper values
            //On the first pass, we split on ? which gives us the To field
            //MessageBox.Show(Line); //This is the line coming into the app
            if (Line.Contains("?"))
            {//Items other than the to were submited
                this.splitTo = (Line.Trim()).Split(new Char[] { '?', '&' });

                //MessageBox.Show(splitTo.Length.ToString(),"# Elements sbmitted:");
                    
                foreach (string a in this.splitTo)
                {
                    //MessageBox.Show("a: " + a);
                    if (a.Contains("bcc="))
                    {//The string holds a carbon copy
                        this.bcc = a;
                    }
                    else if (a.Contains("cc="))
                    {//The string holds a blind carbon copy
                        this.cc = a;
                    }
                    else if (a.Contains("subject="))
                    {//The string holds a subject line
                        this.sub = a.Replace("subject=", "su=");
                    }
                    else if (a.Contains("body="))
                    {//The string contains the body
                        this.body = a;
                    }
                    else
                    {//Catches the Mailto:suckit@bitch.com
                        //MessageBox.Show("Rogue element: " + a);
                    }
                }//end foreach
            }//end the search for elements beyond ?
            else
            {
                //get rid of the mailto: portion of the to string
                this.to = (Line.Split(new char[] { ':' }))[1];
                return new NewEmail(this.to, "", "", "", "");
            }
            this.to = ((this.splitTo[0]).Split(new char[] { ':' }))[1];
            return new NewEmail(this.to, this.cc, this.bcc, this.sub, this.body);
        }//end ParseEmailString
    }//end the settings class

    public class NewEmail
    {//This class is just for holding data (mostly)
        [Obsolete("Member To is obsolete",false)]
        public String To;
        [Obsolete("Member cc is obsolete", false)]
        public String cc;
        [Obsolete("Member bcc is obsolete", false)]
        public String bcc;
        [Obsolete("Member subject is obsolete", false)]
        public String subject;
        [Obsolete("Member body is obsolete", false)]
        public String body;
        public String SendURL;
        private String DefBrowserLocCU = "HKEY_CURRENT_USER\\Software\\Classes\\http\\shell\\open\\command";
        private String DefBrowserLocLM = "HKEY_LOCAL_MACHINE\\Software\\Classes\\http\\shell\\open\\command";
        private String DefaultBroswer;
        private Object BrowserCheck;


        //The last piece of the base url
        //public String Compose_cmd = "?fs=1&view=cm&shva=1";
        public String Compose_cmd = "?extsrc=mailto&url=";
        //https://mail.slu.edu/a/slu.edu?extsrc=mailto&url=
        public String Gmail_URL = "mail.google.com";
        public String Browser_CMD;
        
        public NewEmail(String Mailto_Link)
        {
            this.SendURL = Mailto_Link;
        }
        //This is the constructor for the old version
        [Obsolete("This constructor is obsolete, No need to rebuild the url for google", true)]
        public NewEmail(String ToField, String ccField, String bccField, String subjectField, String BodyField)
        {//Constructor
            this.To = ToField;
            this.cc = ccField;
            this.bcc = bccField;
            this.subject = subjectField;
            this.body = BodyField;

            //Get the default Browser
            //J, get the setting test for null, then look in LM if null
            this.BrowserCheck = (Registry.GetValue(DefBrowserLocCU, "", null));
            if (BrowserCheck == null)
            {
                this.BrowserCheck = (Registry.GetValue(DefBrowserLocLM, "", null));
                if (this.BrowserCheck == null)
                {//Something is wrong, I can't find a default browser
                    //Want to throw an execption here?
                }
                else
                {
                    this.DefaultBroswer = this.BrowserCheck.ToString();
                }
            }
            else
            {
                this.DefaultBroswer = this.BrowserCheck.ToString();
            }
            //MessageBox.Show(this.DefaultBroswer);
        }//end the NewMail Constructor

        public void GetDefaultBrowser()
        {
            this.BrowserCheck = (Registry.GetValue(DefBrowserLocCU, "", null));
            if (BrowserCheck == null)
            {
                this.BrowserCheck = (Registry.GetValue(DefBrowserLocLM, "", null));
                if (this.BrowserCheck == null)
                {//Something is wrong, I can't find a default browser
                    //Want to throw an execption here?
                }
                else
                {
                    this.DefaultBroswer = this.BrowserCheck.ToString();
                }
            }
            else
            {
                this.DefaultBroswer = this.BrowserCheck.ToString();
            }
            //MessageBox.Show(this.DefaultBroswer);
        }

        public void SendEmail(String Domain, String Protocol, String GAFD)
        {
            //MessageBox.Show("Domain: " + Domain + "\n Protocol: " + Protocol + "\n GAFD: " + GAFD,"Stuff");
            //Build the mailto string
            if (GAFD == "true")
            {
                this.SendURL = Protocol + Gmail_URL + "/a/" + Domain + "/" + this.Compose_cmd + this.SendURL;
            }
            else
            {
                this.SendURL = Protocol + Gmail_URL + "/" + this.Compose_cmd + this.SendURL;
            }            
            //MessageBox.Show(this.SendURL, "Full URL");

            GetDefaultBrowser();

            //MessageBox.Show(this.DefaultBroswer.ToString(), "Default Browser");
            if (this.DefaultBroswer.Contains("%1"))
            {
                this.Browser_CMD = this.DefaultBroswer.Replace("%1", this.SendURL);
            }
            else
            {//This only seems to happen in crapy browsers like IE
                this.Browser_CMD = this.DefaultBroswer + "\"" + this.SendURL.Trim() + "\"";
            }                        
            //MessageBox.Show(this.Browser_CMD, "Execute Command:");

            //OK, so now lets try some magic shall we?
            ManagementClass processClass = new ManagementClass("Win32_Process");
            object[] methodArgs = { this.Browser_CMD, null, null, 0 };
            object result = processClass.InvokeMethod("Create", methodArgs);

        }
    }//End NewEmail class
}//end the mailto namespace
